From 49e4882358a2953f349dcb1fbe1c81979d9eaef9 Mon Sep 17 00:00:00 2001 From: Michael Natterer Date: Wed, 14 Dec 2005 12:47:49 +0000 Subject: [PATCH] applied patch from maemo-gtk which avoids the allocation of an 2005-12-14 Michael Natterer * gdk-pixbuf/io-jpeg.c: applied patch from maemo-gtk which avoids the allocation of an intermediate buffer for non-progressive jpegs. Fixed bug #305894. * tests/test-images/valid_jpeg_progressive_test: new test image so we can test both loading code paths in io-jpeg.c --- ChangeLog | 9 +++ ChangeLog.pre-2-10 | 9 +++ gdk-pixbuf/io-jpeg.c | 69 +++++++++++++++++- tests/test-images/valid_jpeg_progressive_test | Bin 0 -> 25206 bytes 4 files changed, 85 insertions(+), 2 deletions(-) create mode 100644 tests/test-images/valid_jpeg_progressive_test diff --git a/ChangeLog b/ChangeLog index 6b0093a178..6e26803288 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2005-12-14 Michael Natterer + + * gdk-pixbuf/io-jpeg.c: applied patch from maemo-gtk which avoids + the allocation of an intermediate buffer for non-progressive + jpegs. Fixed bug #305894. + + * tests/test-images/valid_jpeg_progressive_test: new test image so + we can test both loading code paths in io-jpeg.c + Tue Dec 13 09:47:20 2005 Tim Janik * README.in: added a link to the fgloating reference docs in the diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 6b0093a178..6e26803288 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,12 @@ +2005-12-14 Michael Natterer + + * gdk-pixbuf/io-jpeg.c: applied patch from maemo-gtk which avoids + the allocation of an intermediate buffer for non-progressive + jpegs. Fixed bug #305894. + + * tests/test-images/valid_jpeg_progressive_test: new test image so + we can test both loading code paths in io-jpeg.c + Tue Dec 13 09:47:20 2005 Tim Janik * README.in: added a link to the fgloating reference docs in the diff --git a/gdk-pixbuf/io-jpeg.c b/gdk-pixbuf/io-jpeg.c index fe49c256f0..9c3c064f93 100644 --- a/gdk-pixbuf/io-jpeg.c +++ b/gdk-pixbuf/io-jpeg.c @@ -694,7 +694,7 @@ gdk_pixbuf__jpeg_image_load_increment (gpointer data, int rc; /* start decompression */ - cinfo->buffered_image = TRUE; + cinfo->buffered_image = cinfo->progressive_mode; rc = jpeg_start_decompress (cinfo); cinfo->do_fancy_upsampling = FALSE; cinfo->do_block_smoothing = FALSE; @@ -703,8 +703,73 @@ gdk_pixbuf__jpeg_image_load_increment (gpointer data, continue; context->did_prescan = TRUE; + } else if (!cinfo->buffered_image) { + /* we're decompressing unbuffered so + * get scanline by scanline from jpeg lib + * + * except for handling multiple passes this is + * virtually identical to the next branch + */ + guchar *lines[4]; + guchar **lptr; + guchar *rowptr; + gint nlines, i; + + /* keep going until we've done all scanlines */ + while (cinfo->output_scanline < cinfo->output_height) { + lptr = lines; + rowptr = context->dptr; + for (i=0; i < cinfo->rec_outbuf_height; i++) { + *lptr++ = rowptr; + rowptr += context->pixbuf->rowstride; + } + + nlines = jpeg_read_scanlines (cinfo, lines, + cinfo->rec_outbuf_height); + if (nlines == 0) + break; + + switch (cinfo->out_color_space) { + case JCS_GRAYSCALE: + explode_gray_into_buf (cinfo, lines); + break; + case JCS_RGB: + /* do nothing */ + break; + case JCS_CMYK: + convert_cmyk_to_rgb (cinfo, lines); + break; + default: + if (error && *error == NULL) { + g_set_error (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_UNKNOWN_TYPE, + _("Unsupported JPEG color space (%s)"), + colorspace_name (cinfo->out_color_space)); + } + + return FALSE; + } + + context->dptr += nlines * context->pixbuf->rowstride; + + /* send updated signal */ + (* context->updated_func) (context->pixbuf, + 0, + cinfo->output_scanline-1, + cinfo->image_width, + nlines, + context->user_data); + } + + if (cinfo->output_scanline >= cinfo->output_height) + return TRUE; } else { - /* we're decompressing so feed jpeg lib scanlines */ + /* we're decompressing so feed jpeg lib scanlines + * + * except for handling multiple passes this is + * virtually identical to the previous branch + */ guchar *lines[4]; guchar **lptr; guchar *rowptr; diff --git a/tests/test-images/valid_jpeg_progressive_test b/tests/test-images/valid_jpeg_progressive_test new file mode 100644 index 0000000000000000000000000000000000000000..a8d5c47256f2ea0ef3c523ade68dd23d3c130a25 GIT binary patch literal 25206 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